package com.smx.steppingstone.visitors;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;

import com.smx.steppingstone.util.ReflectUtil;
public class PrintVisitor extends  AbstractVisitor {
	@Override
	public void visitCollection(Collection<?> o, Field f) {
		c(o.getClass().getName(), depth);
		c("[", depth);
		for(Object item:o){
			visit(item);
			c(",", depth);
		}
		c("]", depth);
	}
	
	@Override
	public void visitFloat(Float o, Field f) {		
		if(null == f)
			c("Float : "+o, depth);
		else		
			c("Float : "+f.getName()+"  = "+o, depth);
	}
	
	@Override
	public void visitInteger(Integer o, Field f) {
		if(null == f)
			c("Integer : "+o, depth);
		else		
			c("Integer : "+f.getName()+"  = "+o, depth);
	}

	@Override
	public void visitMethod(Object o, Method m) {
		c(m, depth);
		depth++;
		try{
			visit(ReflectUtil.getMethodValue(o, m));
		}catch(Exception ex){
			//Suppressed ex
		}
		depth--;
	}
	
	@Override
	public void visitObject(Object o, Field f) {
		c((null!=f)?f.getName():""+" "+ o.getClass()+" ",++depth);
		try {
			depth++;
			Field[] fields=o.getClass().getDeclaredFields();							
			for(Field field:fields){	
				if(field.isSynthetic())continue;
				visit(field.get(o), field);
			}
			for(Method method : ReflectUtil.getGetterOrIsMethods(o)){	
				visit(o, method);
			}
			depth--;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		depth--;
	}
	
	@Override
	public void visitString(String o, Field f) {
		if(null == f)
			c("String : "+o, depth);
		else		
			c("String : "+f.getName()+"  = "+o, depth);
	}

	public static void c(Object o, int depth){
		System.out.println("");
		for(int i=1;i<depth;i++)System.out.print("    ");
		System.out.print(o);
	}


}
